package com.db.chat.client;

import com.db.chat.client.network.Configuration;
import com.db.chat.logging.AbstractLogger;
import com.db.chat.logging.FileSyncLogger;
import com.db.chat.logging.LoggerException;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Created by Student on 25.11.2014.
 */
public class ClientConsole {

    private static AbstractLogger logger;

    public static void main(String[] args) {
        try {
            logger = new FileSyncLogger(Configuration.getLoggerPath());
        } catch (LoggerException e) {
            System.out.println("Cannot open log file");
        }
        if (args.length > 0) {
             Configuration.setPort(Integer.valueOf(args[0]));
        }

        InputStream is = null;

        Socket socket = null;
        if (args.length >= 2) {
            //output from another console! open connection through socket instead of console input
            int port = Integer.valueOf(args[1]);
            System.out.println("Input from another socket "+port);
            try (ServerSocket servSocket = new ServerSocket(port)) {
                socket = servSocket.accept();
                is = socket.getInputStream();
            } catch (IOException e) {
                logger.write("Input from socket specified but failed! aborting");
                System.exit(-1);
             }
        }

        try (
                InputStreamReader isr = new InputStreamReader(is == null? System.in : is);
                OutputStreamWriter osw = new OutputStreamWriter(System.out);

                BufferedReader br = new BufferedReader(isr);
                BufferedWriter bw = new BufferedWriter(osw);

                ClientStub clientStub = new ClientStub(logger);

                ) {

            Thread bufferingThread = new Thread(clientStub);
            bufferingThread.start();

            String lineBuffer = new String();

            while(true) {
                if (br.ready()) {

                    String command = br.readLine();
                    switch (command) {
                        case "/exit" :
                            bufferingThread.interrupt();
                            return;
                        default:
                            clientStub.sendMessage(command);
                    }

                    lineBuffer = "";
                }

                if (clientStub.gotMessages()) {

                    System.out.print('\r');
                    System.out.flush();

                    while(System.in.available() > 0) {
                        lineBuffer += (char) isr.read();
                    }


                    for (String message : clientStub.getBufferedMessages()) {
                        bw.write(message, 0, message.length());
                        bw.newLine();
                        bw.flush();
                    }

                    if (lineBuffer.length() > 0) {
                        bw.write(lineBuffer, 0, lineBuffer.length());
                        bw.flush();
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }

        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                logger.write("Failed to close input stream for socket");
            }
        }
        if (socket != null) {
            try {
                socket.close();
            } catch (IOException e) {
                logger.write("Failed to close input socket");
            }
        }
        try {
            logger.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
